package com.wehealth.three.lib_connect.utils;

import android.annotation.SuppressLint;
import android.os.Build;
import android.text.TextUtils;

import androidx.annotation.RequiresApi;

import java.text.SimpleDateFormat;
import java.util.Locale;

/***
 * @author 各种数据类型和byte类型数据的转化的工具类
 */
@SuppressLint("SimpleDateFormat")
public class ByteDataUtil {
    private static SimpleDateFormat dateFormatterForCompare = new SimpleDateFormat("yyyy-MM-dd");
    private static SimpleDateFormat dateFormatterForDisplay = new SimpleDateFormat("MM/dd/yyyy");
    private static SimpleDateFormat timeFormatterForDisplay = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

    //解析唯理板子的导联状态
    public static boolean[] bleParseLeadState(byte[] data) {
        // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
        //V3, V4,V5,V6,RA,LA,LL,V1,V2,RL
        boolean[] leadState = new boolean[]{false, false, false, false, false, false, false, false, false, false};

        if (data[8] == (byte) 0xFC) {
            if (data[7] == (byte) 0xFF) {
                return new boolean[]{true, true, true, true, true, true, true, true, true, true};
            }
            leadState[4] = true;
        }
        if ((data[7] & 0x01) == 1) {//m_stuEcgStatus.statusLA = 1;
            leadState[5] = true;
        }
        if ((data[7] >> 1 & 0x01) == 1) {//m_stuEcgStatus.statusLL = 1;
            leadState[6] = true;
        }
        if ((data[7] >> 2 & 0x01) == 1) {//m_stuEcgStatus.statusC1 = 1;
            leadState[7] = true;
        }
        if ((data[7] >> 3 & 0x01) == 1) {//m_stuEcgStatus.statusC2 = 1;
            leadState[8] = true;
        }
        if ((data[7] >> 4 & 0x01) == 1) {//m_stuEcgStatus.statusC3 = 1;
            leadState[0] = true;
        }
        if ((data[7] >> 5 & 0x01) == 1) {//m_stuEcgStatus.statusC4 = 1;
            leadState[1] = true;
        }
        if ((data[7] >> 6 & 0x01) == 1) {//m_stuEcgStatus.statusC5 = 1;
            leadState[2] = true;
        }
        if ((data[7] >> 7 & 0x01) == 1) {//m_stuEcgStatus.statusC6 = 1;
            leadState[3] = true;
        }
        if (data[7] == (byte) 0xFF) {// m_stuEcgStatus.statusRL = 1;
            return new boolean[]{true, true, true, true, true, true, true, true, true, true};
        }
        return leadState;
    }

    //解析唯理板子的导联状态
    public static String bleParseLead(byte[] data) {
        // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
        //V3, V4,V5,V6,RA,LA,LL,V1,V2,RL
        boolean[] leadState = new boolean[]{false, false, false, false, false, false, false, false, false, false};
        String[] leadStr = new String[]{"V3", "V4", "V5", "V6", "RA", "LA", "LL", "V1", "V2", "RL"};
        if (data[8] == (byte) 0xFC) {
            if (data[7] == (byte) 0xFF) {
                leadState = new boolean[]{true, true, true, true, true, true, true, true, true, true};
            }
            leadState[4] = true;
        }
        if ((data[7] & 0x01) == 1) {//m_stuEcgStatus.statusLA = 1;
            leadState[5] = true;
        }
        if ((data[7] >> 1 & 0x01) == 1) {//m_stuEcgStatus.statusLL = 1;
            leadState[6] = true;
        }
        if ((data[7] >> 2 & 0x01) == 1) {//m_stuEcgStatus.statusC1 = 1;
            leadState[7] = true;
        }
        if ((data[7] >> 3 & 0x01) == 1) {//m_stuEcgStatus.statusC2 = 1;
            leadState[8] = true;
        }
        if ((data[7] >> 4 & 0x01) == 1) {//m_stuEcgStatus.statusC3 = 1;
            leadState[0] = true;
        }
        if ((data[7] >> 5 & 0x01) == 1) {//m_stuEcgStatus.statusC4 = 1;
            leadState[1] = true;
        }
        if ((data[7] >> 6 & 0x01) == 1) {//m_stuEcgStatus.statusC5 = 1;
            leadState[2] = true;
        }
        if ((data[7] >> 7 & 0x01) == 1) {//m_stuEcgStatus.statusC6 = 1;
            leadState[3] = true;
        }
        if (data[7] == (byte) 0xFF) {// m_stuEcgStatus.statusRL = 1;
            leadState = new boolean[]{true, true, true, true, true, true, true, true, true, true};
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < leadState.length; i++) {
            if (leadState[i]) {
                sb.append(leadStr[i]).append("、");
            }
        }
        sb.append(" ").append("电极脱落");
        return sb.toString();
    }

    //解析压缩后的数据
    @RequiresApi(api = Build.VERSION_CODES.O)
    public static int[] bleParsePackECG2(byte[] data) {
        int[] d = new int[16];
        int dataBefore = blePackByte2Int(new byte[]{data[2], data[3], data[4]});
        d[0] = dataBefore;
        for (int i = 5; i < 20; i++) {
            dataBefore = dataBefore + Byte.toUnsignedInt(data[i]) - 128;
            d[i - 4] = dataBefore;
        }
        return d;
    }

    //解析未压缩的数据
    @RequiresApi(api = Build.VERSION_CODES.O)
    public static int[] bleParsePackECG(byte[] data) {
        int[] d = new int[6];
        for (int i = 0; i < 6; i++) {
            d[i] = blePackByte2Int(new byte[]{data[2 + i * 3], data[3 + i * 3], data[4 + i * 3]});
        }
        return d;
    }

    //唯理板子，接收到数据后，需要修正一下
    public static int bleParseGain(byte[] va) {
        return va[9];
    }

    //byte数组转换为int
    @RequiresApi(api = Build.VERSION_CODES.O)
    public static int blePackByte2Int(byte[] bytes) {
        int data;
        if (Byte.toUnsignedInt(bytes[0]) < 128) {
            data = Byte.toUnsignedInt(bytes[0]) * 256 * 256 + Byte.toUnsignedInt(bytes[1]) * 256 + Byte.toUnsignedInt(bytes[2]);
        } else {
            data = Byte.toUnsignedInt(bytes[0]) * 256 * 256 + Byte.toUnsignedInt(bytes[1]) * 256 + Byte.toUnsignedInt(bytes[2]) - 16777216;
        }
        return data;
    }

    public static int toInt(byte[] bytes) {
        switch (bytes.length) {
            case 1:
                return 0xff & bytes[0];
            case 2:
                return ((bytes[0] << 8) & 0xff00) + (bytes[1] & 0xff);
            case 3:
                return ((bytes[0] << 16) & 0xff0000) + ((bytes[1] << 8) & 0xff00) + (bytes[2] & 0xff);
            default:
                return ((bytes[0] << 24) & 0xff000000) + ((bytes[1] << 16) & 0xff0000) + ((bytes[2] << 8) & 0xff00) + (bytes[3] & 0xff);
        }
    }

    public static String toHex(byte[] bytes, String separator) {
        if (bytes == null) {
            return null;
        } else if (bytes.length == 0) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (byte aSrc : bytes) {
            int v = aSrc & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                sb.append(0);
            }
            sb.append(hv);
            if (!TextUtils.isEmpty(separator)) {
                sb.append(separator);
            }
        }
        String s = sb.toString().toUpperCase(Locale.ENGLISH);
        if (!TextUtils.isEmpty(separator)) {
            s = s.substring(0, s.length() - separator.length());
        }
        return s;
    }

    /**
     * byte数组转换成2进制字符串
     *
     * @return 如果bytes为null则返回null，如果bytes长度为0返回""，其他返回正常转换的字符串
     */
    public static String toBinary(byte[] bytes) {
        return toBinary(bytes, " ");
    }

    /**
     * byte数组转换成2进制字符串
     *
     * @param separator 用来分隔的字符串
     * @return 如果bytes为null则返回null，如果bytes长度为0返回""，其他返回正常转换的字符串
     */
    public static String toBinary(byte[] bytes, String separator) {
        if (bytes == null) {
            return null;
        } else if (bytes.length == 0) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (byte aSrc : bytes) {
            int v = aSrc & 0xFF;
            String hv = Integer.toBinaryString(v);
            int loop = 8 - hv.length();
            for (int i = 0; i < loop; i++) {
                sb.append(0);
            }
            sb.append(hv);
            if (!TextUtils.isEmpty(separator)) {
                sb.append(separator);
            }
        }
        String s = sb.toString();
        if (!TextUtils.isEmpty(separator)) {
            s = s.substring(0, s.length() - separator.length());
        }
        return s;
    }


    public static short toShort(byte[] bytes) {
        switch (bytes.length) {
            case 1:
                return (short) (0xff & bytes[0]);
            default:
                return (short) (((bytes[0] << 8) & 0xff00) + (bytes[1] & 0xff));
        }
    }

    public static byte[] toByteArray(int value) {
        return new byte[]{
                (byte) (value >> 24),
                (byte) (value >> 16),
                (byte) (value >> 8),
                (byte) value};
    }

    public static byte[] toByteArray(short value) {
        return new byte[]{
                (byte) (value >> 8),
                (byte) value};
    }


    public static int[] toIntArray(byte[] bytes) {
        int[] ret = new int[bytes.length / 4];
        for (int i = 0; i < bytes.length; ) {
            byte[] tmp = new byte[4];
            for (int j = 0; j < 4; j++) {
                tmp[j] = bytes[i + j];
            }
            ret[i / 4] = toInt(tmp);
            i += 4;
        }
        return ret;
    }

    public static short[] toShortArray(byte[] bytes) {
        short[] ret = new short[bytes.length / 2];
        for (int i = 0; i < bytes.length; ) {
            byte[] tmp = new byte[2];
            for (int j = 0; j < 2; j++) {
                tmp[j] = bytes[i + j];
            }
            ret[i / 2] = toShort(tmp);
            i += 2;
        }
        return ret;
    }

    /**
     * byte[] to short[], every gap number points get one point.
     *
     * @param bytes byte array
     * @param gap   the gap number
     * @return short array
     */
    public static short[] toShortArray(byte[] bytes, int gap) {
        int bLen = bytes.length / 2;
        int retLen = bLen / gap + (bLen % gap == 0 ? 0 : 1);
        int skip = 2 * gap;
        int retIndex = 0;

        short[] ret = new short[retLen];
        for (int i = 0; i < bytes.length; ) {
            byte[] tmp = new byte[2];
            for (int j = 0; j < 2; j++) {
                tmp[j] = bytes[i + j];
            }
            ret[retIndex] = toShort(tmp);

            i += skip;
            retIndex++;
        }

        return ret;
    }

    public static byte[] toByteArray(short[] shorts) {
        byte[] ret = new byte[shorts.length * 2];
        for (int i = 0; i < shorts.length; i++) {
            short value = shorts[i];
            byte[] tmp = toByteArray(value);
            for (int j = 0; j < 2; j++) {
                ret[i * 2 + j] = tmp[j];
            }
        }
        return ret;
    }


    public static byte[] toByteArray(Short[] shorts) {
        byte[] ret = new byte[shorts.length * 2];
        for (int i = 0; i < shorts.length; i++) {
            short value = shorts[i];
            byte[] tmp = toByteArray(value);
            for (int j = 0; j < 2; j++) {
                ret[i * 2 + j] = tmp[j];
            }
        }
        return ret;
    }

    public static byte[] toByteArray(int[] ints) {
        byte[] ret = new byte[ints.length * 4];
        for (int i = 0; i < ints.length; i++) {
            int value = ints[i];
            byte[] tmp = toByteArray(value);
            for (int j = 0; j < 4; j++) {
                ret[i * 4 + j] = tmp[j];
            }
        }
        return ret;
    }

    public static byte[] toByteArray(Integer[] ints) {
        byte[] ret = new byte[ints.length * 4];
        for (int i = 0; i < ints.length; i++) {
            int value = ints[i];
            byte[] tmp = toByteArray(value);
            for (int j = 0; j < 4; j++) {
                ret[i * 4 + j] = tmp[j];
            }
        }
        return ret;
    }
}
